%{
    #include <stdio.h>
    void yyerror(char *s);
    int total=0;
    int skip=0;
%}

%union{
    char operator;
    int num;
}

%token <num> NUM
%token <operator> EOL
%token LESAE GREAE LES GRE EQL NEQ  AND OR NOT LPA RPA ERROR

%type <num> expression logical_expression and_expression not_expression comparison_expression

%left OR
%left AND
%left NOT
%left LESAE GREAE LES GRE EQL NEQ


%%
calclist: /* empty */
| calclist expression EOL { printf("Output: %s,Total: %d,Skip: %d\n> ", $2 ? "TRUE" : "FALSE" ,total,skip); total=0;skip=0;}
| calclist EOL { printf("> "); }
;

expression:logical_expression
;

logical_expression:
    logical_expression OR and_expression { 
        if ($1) {
            skip++;
            $$ = 1;
        } else {
            $$ = $3;
        }
    }
    | and_expression
;

and_expression:
    and_expression AND not_expression { 
        if (!$1) {
            skip++;
            $$ = 0;
        } else {
            $$ = $3;
        }
    }
    | not_expression
;

not_expression:
    NOT not_expression { $$ = !$2; }
    | comparison_expression
;

comparison_expression:NUM {$$ = $1;total++;}
    | NUM LES NUM { $$ = $1 < $3;total++; }
    | NUM GRE NUM { $$ = $1 > $3;total++; }
    | NUM LESAE NUM { $$ = $1 <= $3;total++; }
    | NUM GREAE NUM { $$ = $1 >= $3;total++; }
    | NUM EQL NUM { $$ = $1 == $3;total++; }
    | NUM NEQ NUM { $$ = $1 != $3;total++; }
    | LPA expression RPA {$$ = $2;}
;
%%
void yyerror(char *str){
    fprintf(stderr,"Error:%s\n",str);
}
int yywrap(){
    return 1;
}
int main(){
    yyparse();
    return 0;
}